package com.fujimana.rockincat.restree.web;

import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.fujimana.rockincat.restree.filter.RestreeFilter;
import com.fujimana.rockincat.restree.init.Init;
import com.fujimana.rockincat.restree.service.RestreeService;
import com.fujimana.rockincat.restree.service.Service;

public class RestreeServlet implements Servlet {

	private ServletConfig servletConfig;
	
	private Filter filter;
	
	private Service service;
	
	@Override
	public void destroy() {
		service.destroy();
		filter.destroy();
		
		this.servletConfig = null;
	}
	
	@Override
	public ServletConfig getServletConfig() {
		return this.servletConfig;
	}

	@Override
	public String getServletInfo() {
		return this.getClass().getName();
	}

	@Override
	public void init(ServletConfig servletConfig) throws ServletException {
		this.servletConfig = servletConfig;

		Init init = (Init) this.servletConfig.getServletContext().getAttribute(
				Init.class.getName());
		
		filter = new RestreeFilter(init.getFilters());
		filter.init(new RestreeFilterConfig());
		
		service = new RestreeService();
		service.init(init);
		
		this.servletConfig.getServletContext().removeAttribute(
				Init.class.getName());
	}
	@Override
	public void service(ServletRequest request, ServletResponse response)
			throws ServletException, IOException {
		
		this.filter.doFilter(request, response, new LastFilterChain(this.service));
	}
	
	private class RestreeFilterConfig implements FilterConfig {
		
		@Override
		public String getFilterName() {
			return RestreeFilter.class.getName();
		}

		@Override
		public String getInitParameter(String key) {
			return servletConfig.getServletContext().getInitParameter(key);
		}

		@SuppressWarnings("unchecked")
		@Override
		public Enumeration getInitParameterNames() {
			return servletConfig.getInitParameterNames();
		}

		@Override
		public ServletContext getServletContext() {
			return servletConfig.getServletContext();
		}
		
	}
	
	static class LastFilterChain implements FilterChain {
		
		private Service service;
		
		LastFilterChain(Service service) {
			this.service = service;
		}

		@Override
		public void doFilter(ServletRequest request, ServletResponse response)
				throws IOException, ServletException {
			service.service((HttpServletRequest)request, (HttpServletResponse) response);
		}
		
	}
}
